
#include "archer.h"
#include "towerinfo.h"
#include "gameplayscene.h"
#include "gamemanager.h"
#include "CCSkeletalSprite.h"
#include "arrow.h"
#include "enemy.h"

#define __super			Soldier

Archer::Archer() {

}

Archer::~Archer() {

}

void Archer::handleStateWalk( float ticks )
{
	if(!move(ticks)) {
		if(target) {
			transformState(UnitState::melee);
		} else {
			transformState(UnitState::stand);
		}
	}
}

void Archer::handleStateStand( float ticks )
{
	target = findEnemy();
	if(target) {
		transformState(UnitState::shoot);
	}
}

void Archer::handleStateMelee( float ticks )
{
	if(sprite->animationIsDone()) {
		if(!target){
			transformState(UnitState::stand);
		} else {
			transformState(UnitState::reload);
		}
	}
}

void Archer::handleStateShoot( float ticks )
{
	if(sprite->animationIsDone()) {
		bool lostTarget = !target;
		if(!lostTarget) {
			float distance = target->position.getDistance(position);
			if(distance > attribute.range) {
				lostTarget = true;
			}
		}
		if(lostTarget) {
			transformState(UnitState::stand);
		} else {
			transformState(UnitState::reload);
		}
	}
}

Unit* Archer::findEnemy()
{
	Enemy* ret = nullptr;
	float minDistance = 9999.0f;

	for(Enemy* unit : gamePlayScene->enemies) {
		if(unit->position.x <= 0.0f ||
			unit->position.x >= GM->BASE_WIDTH ||
			unit->position.y <= 0.0f ||
			unit->position.y >= GM->BASE_HEIGHT ||
			fabs(unit->position.x - position.x) > attribute.range ||
			fabs(unit->position.y - position.y) > attribute.range) {
				continue;
		}

		float distance = position.getDistance(unit->position);
		if(distance < minDistance && distance < attribute.range) {
			ret = unit;
			minDistance = distance;
		}
	}

	return ret;
}

void Archer::attack( )
{
	if(target) {
		Bullet* bullet = new Bullet();
		bullet->unitID = id;
		bullet->meleeDamage = attribute.meleeDamage;
		bullet->init();
		target->bullets.push_back(bullet);
	}
}

void Archer::shoot()
{
	if(target) {
		if(target->position.x > position.x) {
			sprite->setFlipX(false);
		} else {
			sprite->setFlipX(true);
		}

		Point from = sprite->getBonePositionRelativeToWorld("bow2");
		Point to = target->sprite->getBonePositionRelativeToWorld("head") + (target->speed * 0.6f);
		
		ArrowBullet* bullet = new ArrowBullet(from, to);
		bullet->unitID = id;
		bullet->rangedDamage = attribute.rangedDamage;
		bullet->target = target;
		bullet->init();
		
		target->bullets.push_back(bullet);
		gamePlayScene->addSceneNode(bullet->sprite);
	}
}

